home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac: Not for Sale / Another.not.for.sale (Australia).iso / hold me in your arms / PGP 2.6 / rsaref Toolkit / source / r_random.c < prev    next >
C/C++ Source or Header  |  1992-02-29  |  3KB  |  112 lines

  1. /* R_RANDOM.C - random objects for RSAREF
  2.  */
  3.  
  4. /* Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
  5.    Security, Inc. All rights reserved.
  6.  */
  7.  
  8. #include "global.h"
  9. #include "rsaref.h"
  10. #include "r_random.h"
  11. #include "md5.h"
  12.  
  13. #define RANDOM_BYTES_NEEDED 256
  14.  
  15. int R_RandomInit (randomStruct)
  16. R_RANDOM_STRUCT *randomStruct;                      /* new random structure */
  17. {
  18.   randomStruct->bytesNeeded = RANDOM_BYTES_NEEDED;
  19.   R_memset ((POINTER)randomStruct->state, 0, sizeof (randomStruct->state));
  20.   randomStruct->outputAvailable = 0;
  21.   
  22.   return (0);
  23. }
  24.  
  25. int R_RandomUpdate (randomStruct, block, blockLen)
  26. R_RANDOM_STRUCT *randomStruct;                          /* random structure */
  27. unsigned char *block;                          /* block of values to mix in */
  28. unsigned int blockLen;                                   /* length of block */
  29. {
  30.   MD5_CTX context;
  31.   unsigned char digest[16];
  32.   unsigned int i, x;
  33.   
  34.   MD5Init (&context);
  35.   MD5Update (&context, block, blockLen);
  36.   MD5Final (digest, &context);
  37.  
  38.   /* add digest to state */
  39.   x = 0;
  40.   for (i = 0; i < 16; i++) {
  41.     x += randomStruct->state[15-i] + digest[15-i];
  42.     randomStruct->state[15-i] = (unsigned char)x;
  43.     x >>= 8;
  44.   }
  45.   
  46.   if (randomStruct->bytesNeeded < blockLen)
  47.     randomStruct->bytesNeeded = 0;
  48.   else
  49.     randomStruct->bytesNeeded -= blockLen;
  50.   
  51.   /* Zeroize sensitive information.
  52.    */
  53.   R_memset ((POINTER)digest, 0, sizeof (digest));
  54.   x = 0;
  55.   
  56.   return (0);
  57. }
  58.  
  59. int R_GetRandomBytesNeeded (bytesNeeded, randomStruct)
  60. unsigned int *bytesNeeded;                 /* number of mix-in bytes needed */
  61. R_RANDOM_STRUCT *randomStruct;                          /* random structure */
  62. {
  63.   *bytesNeeded = randomStruct->bytesNeeded;
  64.   
  65.   return (0);
  66. }
  67.  
  68. int R_GenerateBytes (block, blockLen, randomStruct)
  69. unsigned char *block;                                              /* block */
  70. unsigned int blockLen;                                   /* length of block */
  71. R_RANDOM_STRUCT *randomStruct;                          /* random structure */
  72. {
  73.   MD5_CTX context;
  74.   unsigned int available, i;
  75.   
  76.   if (randomStruct->bytesNeeded)
  77.     return (RE_NEED_RANDOM);
  78.   
  79.   available = randomStruct->outputAvailable;
  80.   
  81.   while (blockLen > available) {
  82.     R_memcpy
  83.       ((POINTER)block, (POINTER)&randomStruct->output[16-available],
  84.        available);
  85.     block += available;
  86.     blockLen -= available;
  87.  
  88.     /* generate new output */
  89.     MD5Init (&context);
  90.     MD5Update (&context, randomStruct->state, 16);
  91.     MD5Final (randomStruct->output, &context);
  92.     available = 16;
  93.  
  94.     /* increment state */
  95.     for (i = 0; i < 16; i++)
  96.       if (randomStruct->state[15-i]++)
  97.         break;
  98.   }
  99.  
  100.   R_memcpy 
  101.     ((POINTER)block, (POINTER)&randomStruct->output[16-available], blockLen);
  102.   randomStruct->outputAvailable = available - blockLen;
  103.  
  104.   return (0);
  105. }
  106.  
  107. void R_RandomFinal (randomStruct)
  108. R_RANDOM_STRUCT *randomStruct;                          /* random structure */
  109. {
  110.   R_memset ((POINTER)randomStruct, 0, sizeof (*randomStruct));
  111. }
  112.